home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gekikoh Dennoh Club 5
/
Gekikoh Dennoh Club Vol. 5 (Japan).7z
/
Gekikoh Dennoh Club Vol. 5 (Japan) (Track 01).bin
/
internet
/
xip
/
iijppp.lzh
/
test
/
tunecho.c
< prev
Wrap
C/C++ Source or Header
|
1994-10-11
|
4KB
|
172 lines
/*
* tunnel driver test program.
*
* This program does ICMP echo reply. Can be used to measure
* overhead of tunnel driver and associated process.
*/
#include <machine/endian.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <net/route.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <net/if.h>
#if defined(__NetBSD__) || _BSDI_VERSION >= 199312
#include <sys/select.h>
#endif
#include <net/if_tun.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <signal.h>
int tun;
struct ifaliasreq ifra;
static void
IcmpEcho(ptr, nb)
u_char *ptr;
int nb;
{
struct ip *pip;
struct icmp *picmp;
struct in_addr w;
/* Validate IP header */
pip = (struct ip *)ptr;
if (pip->ip_v != IPVERSION)
return;
if (pip->ip_p != IPPROTO_ICMP)
return;
/* Validate ICMP header */
picmp = (struct icmp *)(ptr + (pip->ip_hl << 2));
if (picmp->icmp_type != ICMP_ECHO)
return;
/* Build reply packet */
picmp->icmp_type = ICMP_ECHOREPLY;
picmp->icmp_cksum += 8;
w = pip->ip_src;
pip->ip_src = pip->ip_dst;
pip->ip_dst = w;
write(tun, ptr, nb);
}
void
gotinter()
{
int s;
s = socket(AF_INET, SOCK_DGRAM, 0);
bzero(&ifra.ifra_addr, sizeof(ifra.ifra_addr));
bzero(&ifra.ifra_broadaddr, sizeof(ifra.ifra_addr));
bzero(&ifra.ifra_mask, sizeof(ifra.ifra_addr));
ioctl(s, SIOCDIFADDR, &ifra);
close(tun);
exit(0);
}
struct tuninfo tuninfo;
main()
{
int s;
int one = 1;
int val, nb;
struct ifreq ifrq;
char ifname[IFNAMSIZ];
struct sockaddr_in *sin;
char iobuff[500];
fd_set rfds;
tun = open("/dev/tun0", O_RDWR);
if (tun < 0) {
perror("open");
exit(1);
}
/*
* At first, name the interface.
*/
strcpy(ifname, "tun0");
bzero((char *)&ifra, sizeof(ifra));
bzero((char *)&ifrq, sizeof(ifrq));
strncpy(ifrq.ifr_name, ifname, IFNAMSIZ);
strncpy(ifra.ifra_name, ifname, IFNAMSIZ);
/*
* Set interface address
*/
sin = (struct sockaddr_in *)&(ifra.ifra_addr);
sin->sin_family = AF_INET;
val = inet_addr("100.123.111.2");
sin->sin_addr.s_addr = val;
sin->sin_len = sizeof(*sin);
/*
* Set destination address
*/
sin = (struct sockaddr_in *)&(ifra.ifra_broadaddr);
sin->sin_family = AF_INET;
val = inet_addr("100.123.111.8");
sin->sin_addr.s_addr = val;
sin->sin_len = sizeof(*sin);
/*
*/
sin = (struct sockaddr_in *)&(ifra.ifra_mask);
sin->sin_family = AF_INET;
val = inet_addr("255.255.255.255");
sin->sin_addr.s_addr = val;
sin->sin_len = sizeof(*sin);
s = socket(AF_INET, SOCK_DGRAM, 0);
if (s < 0) {
perror("socket");
exit(1);
}
if (ioctl(s, SIOCAIFADDR, &ifra) < 0) {
perror("SIOCAIFADDR");
exit(1);
}
/*
* Now, bring up the interface.
*/
if (ioctl(s, SIOCGIFFLAGS, &ifrq) < 0) {
perror("SIOCGIFFLAGS");
exit(1);
}
ifrq.ifr_flags |= IFF_UP;
if (ioctl(s, SIOCSIFFLAGS, &ifrq) < 0) {
perror("SIOCSIFFLAGS");
exit(1);
}
close(s);
printf("Interface is now up!! (%d)\n", tun);
signal(SIGINT, gotinter);
val = ioctl(tun, TUNGIFINFO, &tuninfo);
printf("val = %d\n", val);
printf("TYPE = %d, MTU = %d\n", tuninfo.if_type, tuninfo.if_mtu);
for (;;) {
FD_ZERO(&rfds);
FD_SET(0, &rfds); FD_SET(tun, &rfds);
if (select(tun + 2, &rfds, NULL, NULL, NULL) < 0)
break;
if (FD_ISSET(tun, &rfds)) {
nb = read(tun, iobuff, sizeof(iobuff));
IcmpEcho(iobuff, nb);
}
if (FD_ISSET(0, &rfds)) {
read(0, iobuff, sizeof(iobuff));
break;
}
}
}